﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SqlServer.Server;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public partial class CreateFloor2 : System.Web.UI.Page
{
    //private string[] _rows = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"};
    private Layout _layout;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!string.IsNullOrEmpty(Request.QueryString.ToString()))
        {
            int rows = Convert.ToInt32(Request.QueryString["rows"]);
            int seats = Convert.ToInt32(Request.QueryString["seats"]);
            CreateScreenTemplate2(rows, seats);
        }
    }

    protected void SendInfo(object sender, EventArgs e)
    {
        int rows = Convert.ToInt32(DropDownListRows.Text);
        int seats = Convert.ToInt32(DropDownListSeats.Text);
        Response.Redirect("CreateFloor2.aspx?rows="+rows+"&seats="+seats+"");
    }

    protected void CreateScreenTemplate2(int rows, int seats)
    {
        int rowCounter = 1;
        int seatCounter = 1;
        string rowUnique = "r";
        string seatUnique = "s";
        Panel linebreakDiv = new Panel { CssClass = "LineBreak" };

        while (rowCounter <= rows)
        {
            String rowId = rowUnique + rowCounter;
            Panel newRow = new Panel { CssClass = "Row", ID = rowId };

            while (seatCounter <= seats)
            {
                string seatId = seatUnique + seatCounter;
                Panel seatBox = new Panel { CssClass = "SeatBox" };
                Panel seat = new Panel { CssClass = "Seat SeatAvailable" };

                //seat.Click += PickSeat;
                seat.Attributes.Add("id", String.Format("{0}{1}", rowId, seatId));
                //seat.Attributes.Add("onClick", String.Format("selectOrDeselectSeat('{0}{1}');", rowId, seatId));
                seatBox.Controls.Add(seat);
                newRow.Controls.Add(seatBox);
                //FloorDiv.Controls.Add(seatBox);
                seatCounter++;
            }
            seatCounter = 1;
            FloorDiv.Controls.Add(newRow);
            //FloorDiv.Controls.Add(linebreakDiv);
            rowCounter++;
        }
    }

    /*protected void CreateScreenTemplate(object sender, EventArgs e)
    {
        int rowCounter = 1;
        int seatCounter = 1;
        int seatUnique = 100000;
        int rows = Convert.ToInt32(DropDownListRows.Text);
        int seats = Convert.ToInt32(DropDownListSeats.Text);

        while (rowCounter <= rows)
        {
            String rowId = Convert.ToString(10000 + rowCounter);
            Panel newRow = new Panel {CssClass = "Row", ID = rowId};

            while (seatCounter <= seats)
            {
                string seatId = Convert.ToString(seatCounter + seatUnique);
                Panel seatBox = new Panel {CssClass = "SeatBox"};
                Button seat = new Button {CssClass = "Seat SeatAvailable", ID = seatId, Text = "1"};
                seat.Click += PickSeat;
                seatBox.Controls.Add(seat);
                newRow.Controls.Add(seatBox);
                seatCounter++;
            }
            seatCounter = 1;
            seatUnique += 100000;
            FloorDiv.Controls.Add(newRow);
            rowCounter++;
        }
    }*/

    /*protected void CreateFloorDesigner(object sender, EventArgs e)
    {
        int counter = 1;
        foreach (string row in _rows)
        {
            Panel newRow = new Panel { CssClass = "Row" };

            while (counter < 31)
            {
                Panel seat = new Panel { CssClass = "SeatBox" };

                Button b = new Button { CssClass = "Seat SeatAvailable", ID = row + counter, Text = "1" };
                b.Click += PickSeat;

                seat.Controls.Add(b);
                newRow.Controls.Add(seat);
                counter++;
            }

            FloorDiv.Controls.Add(newRow);
            counter = 1;
        }
    }*/

    /*protected void PickSeat(object sender, EventArgs e)
    {
        Button b = (Button)sender;
        string bText = b.Text;

        if (bText.Equals("1"))
        {
            b.CssClass = "Seat SeatDisabled";
            b.Text = "0";
        }
        else
        {
            b.CssClass = "Seat SeatAvailable";
            b.Text = "1";
        }
    }*/
    
    protected void btnLayoutDone_Click(object sender, EventArgs e)
    {
        btnCreateScreenDesigner.Enabled = false;
        btnLayoutDone.Enabled = false;

        FloorDiv.Attributes.Add("style", "display:none;");
        
        int rows = Convert.ToInt32(Request.QueryString["rows"]);
        int seatsInRow = Convert.ToInt32(Request.QueryString["seats"]);

        CalculateRowsAndSeatsScore(rows, 0, seatsInRow, true);

        showVisuScoreBoard();

    }

    private void CalculateRowsAndSeatsScore(int rows, int preferedRow, int seatsInRow, Boolean doCalcTest)
    {
        Layout layout = new Layout(0, "Layout Test");
        int rCount = 1;
        int sCount = 1;

        #region Creating a dictionary from JSON data sent from the frontend, where the user (de)activates seats
        //      FORTSAT:: Later on the scores is added and then all the data is merged into Row and Seat classes

        Dictionary<string, string> seatsDictionary = new Dictionary<string, string>();

        string jsonStream = json.Value;

        dynamic dynJson = JsonConvert.DeserializeObject(jsonStream);
        foreach (var item in dynJson.seats)
        {
            seatsDictionary.Add(""+item.id, ""+item.available);
        }
        #endregion

        #region Foreach - Row scores (inside also Foreach: Score per seat)
        foreach (int rowScore in CalculateScorePerRow(rows, preferedRow))
        {
            //Panel newRow = new Panel { CssClass = "Row", ID = ""+rCount };
            sCount = 1;
            Row newRow = new Row(0, ""+rCount);

            #region Foreach Score per seat
            foreach (int seatScore in CalculateScorePerSeatInRow(seatsInRow))
            {
                //Panel seatBox = new Panel { CssClass = "SeatBox" };
                //Panel seat = new Panel { CssClass = "Seat SeatAvailable" };
                int score = seatScore + rowScore;

                /*
                  {
                      "seats": [
                                  {
                                      "id": "r1s1",
                                      "available": true
                                  },
                                  {   "id": "r1s2",
                                      "available": true
                                  }
                               ]
                               
                  }
                 */

                string seatIdentifier = String.Format("r{0}s{1}", rCount, sCount);
                bool isSeat = false;
                string value = "";

                if (seatsDictionary.TryGetValue(seatIdentifier, out value))
                {
                    if (value.Equals("true"))
                    {
                        isSeat = true;
                    }
                }

                Seat newSeat = new Seat(0, ""+sCount, isSeat, score);

                newRow.AddSeat(newSeat);

                //seat.Controls.Add(new LiteralControl(""+(seatScore + rowScore)));

                //seatBox.Controls.Add(seat);
                //newRow.Controls.Add(seatBox);

                sCount++;

            }
            #endregion


            //Console.WriteLine("{0}", seats);
            //----FloorScore.Controls.Add(newRow);

            layout.AddRow(newRow);

            rCount++;
        }
#endregion

        _layout = layout;
    }

    private List<int> CalculateScorePerRow(int numRows, int preferredRow)
    {
        List<int> rowsList = new List<int>();

        double theCenter = numRows / 2;
        int theCenter2 = (int)Math.Ceiling(theCenter);

        int outputInt = 0;

        if (preferredRow == 0)
        {

            int x = numRows;
            for (int i = 1; i <= numRows; i++)
            {
                if (i <= theCenter2)
                {
                    outputInt = i; // 1 og 2
                }
                else
                {
                    outputInt = x; // 8, 7, 6, 5, 4, 3, 2, 1
                }

                rowsList.Add(outputInt);

                x--;
            }

        }
        else
        {
            // Vi har 10 rækker (rows)
            int rows = numRows;
            // Vores fortrukne række er 2 (prefRow)
            int prefRow = preferredRow;

            // (rows)10 minus 1 - for at give det nummer vi går ud fra
            int maxScore = rows - 1;
            // (prefRow)5-1 - antallet af rækker vi skal have før række 5
            int numbersOfRowsBeforeTheRowWeGoOutFrom = prefRow - 1;
            // (rows)10-(prefRow)5 - antallet af rækker der skal være efter
            int numbersOfRowsAfterTheRowWeGoOutFrom = rows - prefRow;


            rowsList.Add(maxScore); // Tilføjer først den miderste linje. Altså den hvor scoren er højest, vores preferredRow

            // I dette for-loop tilføjer vi alle "rows"/rækkerne som kommer efter vores preferredRow
            for (int i = 1; i <= numbersOfRowsAfterTheRowWeGoOutFrom; i++)
            {
                rowsList.Add(maxScore - i);
            }

            // I dette for-loop nr. 2, der løber vi de første "rows"/rækker igennem. Disse bliver smidt ind i starten af array'et
            for (int i = 1; i <= numbersOfRowsBeforeTheRowWeGoOutFrom; i++)
            {
                rowsList.Insert(0, maxScore - i);//maxScore-xTry);
            }


            //////////////////////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////////////////////
            ///////////////////////////////////  Tidligere noter!  ///////////////////////////////////
            //////////////////////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////////////////////
            //////////////////////////////////////////////////////////////////////////////////////////


            // Vi har 10 rækker
            // Vores fortrukne række er 2
            //#1   8
            //#2   9 --
            //#3   8
            //#4   7
            //#5   6
            //#6   5
            //#7   4
            //#8   3
            //#9   2
            //#10  1

            // Vi har 10 rækker (rows)
            // Vores fortrukne række er 5 (prefRow)

            // (rows)10 minus 1 - for at give det nummer vi går ud fra
            // (prefRow)5-1 - antallet af rækker vi skal have før række 5
            // (rows)10-(prefRow)5 - antallet af rækker der skal være efter

            //#1   5
            //#2   6
            //#3   7
            //#4   8
            //#5   9 --
            //#6   8
            //#7   7
            //#8   6
            //#9   5
            //#10  4


        }

        return rowsList;
    }

    private List<int> CalculateScorePerSeatInRow(int spr)
    {
        int sprResult = spr / 2; // Del SPR (seats per row) i 2, hvis tallet ikke er helt, vil der blive rundet ned. (decimaler fjernes)
        List<int> output = new List<int>();

        int x = spr; // X er vores tal vi tæller baglæns.
         

        for (int i = 1; i <= spr; i++)
        {
            int outputInt = 0;

            outputInt = i <= sprResult ? i : x; // Hvis er mindre eller ligmed sprResult (spr delt i to) så er outputInt = i eller er det = x

            #region Forsøg på visuel forklaring af algoritmen.
            /** 
             
            1 - i
            2 - i
            3 - i
            4 - i
            5 - i - Dette er vores sprResult
            6 - x
            7 - x
            8 - x
            9 - x
            
            **/
            #endregion
            output.Add(outputInt);

            x--;
        }

        return output;
    }

    private void showVisuScoreBoard()
    {
        string layoutLines = "";

        foreach (Row row in _layout.GetListOfRows())
        {
            string rowLine = "";

            foreach (Seat seat in row.GetListOfSeats())
            {

                rowLine += formatThis(seat.Score);
            }

            layoutLines += rowLine + "\n";
        }

        json2.InnerText = layoutLines;
    }

    private string formatThis(int score)
    {
        string str = "";  //    String.Format(" {0} ", score)

        if (score < 10)
        {
            str = String.Format(" {0} ", score);
        }
        else if (score < 100)
        {
            str = String.Format(" {0}", score);
        }

        else if (score < 1000)
        {
            str = String.Format("{0}", score);
        }
        else
        {
            str = " ERR ";
        }

        return str;
    }
}